#!/usr/bin/env python
# encoding: utf-8
"""
Shovelhead
File: VTwin.py
Author: Myriam Boucher

Sound synthesis of a V Twin engine.

A V-twin engine is a two-cylinder internal combustion engine where the cylinders are arranged in a V configuration.
Source: <http://en.wikipedia.org/wiki/V-twin_engine>.
"""

from pyo import *
import random
import math
from LoopAdsr import *
from Gear import *
from Engine import *
import time

class VTwin(Engine):
    
    def __init__(self):
        Engine.__init__(self)  

        # effects on its rattling engine, noise
        self.noiseResonnance = PinkNoise(mul=self.env2.sig(), add=0)
        self.r5 = Randi(min=0.25, max=.27, freq=1.00, mul=1, add=0)
        self.r6 = Randi(min=0.16, max=.17, freq=1.00, mul=1, add=0)
        self.noiseResonnance2 = Noise(.2)
        self.r9 = Randi(min=0.10, max=.11, freq=[2.1,2.2, 1.1,1.5], mul=1, add=0)
        self.resonnanceEngine2 = IRPulse(self.noiseResonnance2, freq=self.r9*1500, bw=3200, type=2, order=152,
                                         mul = [.5, self.env.sig()])
        self.disto = Disto(  self.fm + self.fm2  + self.resonnanceEngine2
                         , drive=0.32, slope=0.45, mul=1, add=0)
        self.clipVtwin = Clip(self.disto, min=-1.00, max=1.00, mul=1, add=0)
        self.pan2DVTwin = SPan(self.eqPinkNoise + self.clipVtwin  + self.filterSinwave, outs=2, pan=0.50, mul=.5, add=0)
        self.setPan2D(self.pan2DVTwin)
        self.eq = EQ(self.pan2DVTwin, freq=8000, q=10, boost=5.00, type=2, mul=1, add=0)
        self.mixVTwin = Mix(self.eq, voices=2)
        self.setMix(self.mixVTwin)
        
        # kickStart: crankshaft sound
        self.env4 = LoopAdsr(list=[(0,0),(250,1),(1000,0.0005),(1200,0.0005),(1350,0)],
                dur=0.09, min=0.01, max=0.03, freq=[10,10.2])
        self.pinkNoiseKS = PinkNoise(mul=self.env4.sig(), add=0)
        self.revKickStart = WGVerb(self.pinkNoiseKS, feedback=0.50, cutoff=5000, bal=0.32, mul=.38, add=0)
        self.mixNoStartingVTwin = Mix(self.revKickStart)
        self.setMixNoStarting(self.mixNoStartingVTwin)
        
    def changeSpeed(self, x):  
        # changes the sound of the engine when changing speed.
        self.fm.carrier += x*5
        self.fm.ratio += x/15
        self.fm.ind1 *= x*10
        self.fm.ind2 += x*1.5
        self.sinwave.freq += x*3
        self.fm2.carrier += x*10
        self.fm2.ratio += x/10
        self.fm2.ind1 *= x*10
        self.fm2.ind2 += x*3

    def playVTwin(self):
        # plays the audio objects.
        self.clipVtwin.play()
        self.resonnanceEngine2.play()
        self.noiseResonnance2.play()
        self.noiseResonnance.play()
        self.disto.play()
        self.pan2DVTwin.play()
        self.eq.play()
        self.r5.play()
        self.r6.play()
        self.r9.play()
        self.eq.play()
        self.pinkNoiseKS.play()
        self.revKickStart.play()
        
        
    def stopVTwin(self):
        # stop the audio objects.
        self.clipVtwin.stop()
        self.resonnanceEngine2.stop()
        self.noiseResonnance2.stop()
        self.noiseResonnance.stop()
        self.disto.stop()
        self.pan2DVTwin.stop()
        self.eq.stop()
        self.r5.stop()
        self.r6.stop()
        self.r9.stop()
        self.eq.stop()
        self.pinkNoiseKS.stop()
        self.revKickStart.stop()
        
    